﻿namespace HREngine.Bots
{
    public class BehaviorSecretMage : Behavior
    {
        public override string BehaviorName() { return "SecretMage"; }


        PenalityManager penman = PenalityManager.Instance;

        public override float getPlayfieldValue(Playfield p)
        {
            if (p.value >= -2000000) return p.value;
            int retval = 0;
            // 奥秘存在的价值，至少要比手牌价值高才会主动放奥秘
            retval += p.ownSecretsIDList.Count * 4;
            retval -= p.evaluatePenality;
            retval += p.owncards.Count * 3;
            retval += p.ownQuest.questProgress * 10;

            retval += p.ownHero.Hp + p.ownHero.armor;
            retval += -(p.enemyHero.Hp + p.enemyHero.armor);

            retval += p.ownMaxMana * 15 - p.enemyMaxMana * 15;

            if (p.ownHeroPowerAllowedQuantity != p.enemyHeroPowerAllowedQuantity)
            {
                if (p.ownHeroPowerAllowedQuantity > p.enemyHeroPowerAllowedQuantity) retval += 1;
                else retval -= 4;
            }

            if (p.ownWeapon.Angr >= 1)
            {
                retval += p.ownWeapon.Angr * p.ownWeapon.Durability;
            }

            if (!p.enemyHero.frozen)
            {
                retval -= p.enemyWeapon.Durability * p.enemyWeapon.Angr;
            }
            else
            {
                if (p.enemyHeroName != HeroEnum.mage && p.enemyHeroName != HeroEnum.priest)
                {
                    retval += 11;
                }
            }

            //RR card draw value depending on the turn and distance to lethal
            //RR if lethal is close, carddraw value is increased
            if (p.lethalMissing() <= 5) //RR
            {
                retval += p.owncarddraw * 100;
            }
            if (p.ownMaxMana < 4)
            {
                retval += p.owncarddraw * 2;
            }
            else
            {
                retval += p.owncarddraw * 5;
            }
            retval += p.owncarddraw * 5;
            if (p.owncarddraw + 1 >= p.enemycarddraw) retval -= p.enemycarddraw * 7;
            else retval -= (p.owncarddraw + 1) * 7 + (p.enemycarddraw - p.owncarddraw - 1) * 12;

            bool useAbili = false;
            int usecoin = 0;
            foreach (Action a in p.playactions)
            {
                if (a.actionType == actionEnum.attackWithHero && p.enemyHero.Hp <= p.attackFaceHP) retval++;
                if (a.actionType == actionEnum.useHeroPower) useAbili = true;
                if (p.ownHeroName == HeroEnum.warrior && a.actionType == actionEnum.attackWithHero && useAbili) retval -= 1;
                //if (a.actionType == actionEnum.useHeroPower && a.card.card.name == CardDB.cardName.lesserheal && (!a.target.own)) retval -= 5;
                if (a.actionType != actionEnum.playcard) continue;
                if (a.card.card.name == CardDB.cardName.thecoin || a.card.card.name == CardDB.cardName.innervate) usecoin++;

                if (a.card.card.type == CardDB.cardtype.SPELL && a.card.card.name == CardDB.cardName.fireball && (a.target.isHero && !a.target.own)) retval += 2;
                if (a.card.card.type == CardDB.cardtype.SPELL && a.card.card.name == CardDB.cardName.roaringtorch && (a.target.isHero && !a.target.own)) retval += 2;
                if (a.card.card.Secret) retval += 5;
            }
            if (usecoin > 0)
            {
                if (useAbili && p.ownMaxMana <= 2) retval -= 40;
                retval -= 5 * p.manaTurnEnd;
                if (p.manaTurnEnd + usecoin > 10) retval -= 5 * usecoin;
            }
            if (p.manaTurnEnd >= p.ownHeroAblility.manacost && !useAbili && p.ownAbilityReady)  // 不应该固定为2，因为有偶数系列
            {
                switch (p.ownHeroAblility.card.name)
                {
                    case CardDB.cardName.heal: goto case CardDB.cardName.lesserheal;
                    case CardDB.cardName.lesserheal:
                        bool wereTarget = false;
                        if (p.ownHero.Hp < p.ownHero.maxHp) wereTarget = true;
                        if (!wereTarget)
                        {
                            foreach (Minion m in p.ownMinions)
                            {
                                if (m.wounded) { wereTarget = true; break; }
                            }
                        }
                        if (wereTarget && !(p.anzOwnAuchenaiSoulpriest > 0 || p.embracetheshadow > 0)) retval -= 10;
                        break;
                    case CardDB.cardName.poisoneddaggers: goto case CardDB.cardName.daggermastery;
                    case CardDB.cardName.daggermastery:
                        if (!(p.ownWeapon.Durability > 1 || p.ownWeapon.Angr > 1)) retval -= 10;
                        break;
                    case CardDB.cardName.totemicslam: goto case CardDB.cardName.totemiccall;
                    case CardDB.cardName.totemiccall:
                        if (p.ownMinions.Count < 7) retval -= 10;
                        else retval -= 3;
                        break;
                    case CardDB.cardName.thetidalhand: goto case CardDB.cardName.reinforce;
                    case CardDB.cardName.thesilverhand: goto case CardDB.cardName.reinforce;
                    case CardDB.cardName.reinforce:
                        if (p.ownMinions.Count < 7) retval -= 10;
                        else retval -= 3;
                        break;
                    case CardDB.cardName.soultap:
                        if (p.owncards.Count < 10 && p.ownDeckSize > 0) retval -= 10;
                        break;
                    case CardDB.cardName.lifetap:
                        if (p.owncards.Count < 10 && p.ownDeckSize > 0)
                        {
                            retval -= 10;
                            if (p.ownHero.immune) retval -= 5;
                        }
                        break;
                    default:
                        retval -= 10;
                        break;
                }
            }
            //if (usecoin && p.mana >= 1) retval -= 20;

            foreach (Minion m in p.ownMinions)
            {
                retval += m.Hp * 1;
                retval += m.Angr * 2;
                //retval += m.handcard.card.rarity;  稀有度不应该加分
                if (m.windfury) retval += m.Angr;
                if (m.taunt) retval += 1;
                if (!m.taunt && m.stealth && m.handcard.card.isSpecialMinion && !m.silenced) retval += 20;
                if (m.handcard.card.name == CardDB.cardName.silverhandrecruit && m.Angr == 1 && m.Hp == 1) retval -= 5;
                if (p.ownMinions.Count > 1 && (m.handcard.card.name == CardDB.cardName.direwolfalpha || m.handcard.card.name == CardDB.cardName.flametonguetotem || m.handcard.card.name == CardDB.cardName.stormwindchampion || m.handcard.card.name == CardDB.cardName.raidleader || m.handcard.card.name == CardDB.cardName.fallenhero)) retval += 10;
                if (m.handcard.card.name == CardDB.cardName.nerubianegg)
                {
                    if (m.Angr >= 1) retval += 2;
                    if ((!m.taunt && m.Angr == 0) && (m.divineshild || m.maxHp > 2)) retval -= 10;
                }
                retval += m.synergy;
            }

            foreach (Handmanager.Handcard hc in p.owncards)
            {
                if (hc.card.type == CardDB.cardtype.MOB)
                {
                    retval += hc.addattack + hc.addHp + hc.elemPoweredUp;
                }
            }

            int tmp = 0;
            foreach (Minion m in p.enemyMinions)
            {
                tmp += this.getEnemyMinionValue(m, p);
                // Todo:场上尽量不要有specialMinions里面的随从
                if (penman.specialMinions.ContainsKey(m.name) && m.Hp > 0)
                    tmp += 30;  // 每有一个special随从，加60惩罚值
            }
            if (p.enemyMinions.Count == 1) tmp /= 2;
            retval -= tmp;

            retval -= p.enemySecretCount;
            retval -= p.lostDamage;//damage which was to high (like killing a 2/1 with an 3/3 -> => lostdamage =2
            retval -= p.lostWeaponDamage;
            if (p.ownMinions.Count == 0) retval -= 20;
            if (p.enemyMinions.Count >= 4) retval -= 20;
            if (p.enemyHero.Hp <= 0) retval = 10000;

            retval += p.anzOwnExtraAngrHp - p.anzEnemyExtraAngrHp / 2;
            //soulfire etc
            int deletecardsAtLast = 0;
            foreach (Action a in p.playactions)
            {
                if (a.actionType != actionEnum.playcard) continue;
                if (a.card.card.name == CardDB.cardName.soulfire || a.card.card.name == CardDB.cardName.doomguard || a.card.card.name == CardDB.cardName.queenofpain) deletecardsAtLast = 1;
                if (deletecardsAtLast == 1 && !(a.card.card.name == CardDB.cardName.soulfire || a.card.card.name == CardDB.cardName.doomguard || a.card.card.name == CardDB.cardName.queenofpain)) retval -= 20;
            }
            if (p.enemyHero.Hp >= 1 && p.guessingHeroHP <= 0)
            {
                if (p.turnCounter < 2) retval += p.owncarddraw * 500;
                retval -= 1000;
            }
            if (p.ownHero.Hp <= 0) retval -= 10000;

            p.value = retval;
            return retval;
        }

        public override int getEnemyMinionValue(Minion m, Playfield p)
        {
            int retval = 0;
            if (p.enemyMinions.Count >= 4 || m.taunt || (m.handcard.card.targetPriority >= 1 && !m.silenced) || m.Angr >= 5)
            {
                retval += m.Hp;
                if (!m.frozen && !(m.cantAttack && m.name != CardDB.cardName.argentwatchman))
                {
                    retval += m.Angr * 2;
                    if (m.windfury) retval += 2 * m.Angr;
                }
                if (m.taunt) retval += 5;
                if (m.divineshild) retval += m.Angr;
                if (m.frozen) retval -= 1; // because its bad for enemy :D
                if (m.poisonous)
                {
                    retval += 4;
                    if (p.ownMinions.Count < p.enemyMinions.Count) retval += 10;
                }
                if (m.lifesteal) retval += m.Angr;
                if (m.handcard.card.isSpecialMinion) retval += m.handcard.card.rarity;
            }

            retval += m.synergy;
            if (m.handcard.card.targetPriority >= 1 && !m.silenced) retval += m.handcard.card.targetPriority;
            if (m.Angr >= 5) retval += 20; //奥秘法侧重抢脸，4->5，避免去解 444隐秘咒术师 544云雾王子
            if (m.Angr >= 7) retval += 50;
            if (m.name == CardDB.cardName.nerubianegg && m.Angr <= 3 && !m.taunt) retval = 0;
            return retval;
        }

        public override int getComboPenality(CardDB.Card card, Minion target, Playfield p)
        {
            int pen = 0;
            bool zeroSecret = p.nextSecretThisTurnCost0; //手牌是否有0费的奥秘存在
            bool hasSecretHand = false;  //手牌是否有奥秘
            bool hasSecretHead = (p.ownSecretsIDList.Count >= 1); //头上有奥秘
            foreach (Handmanager.Handcard hc in p.owncards)
            {
                if (hc.card.Secret)
                {
                    hasSecretHand = true;
                    break;
                }
            }

            bool needSecret = false;
            foreach (Handmanager.Handcard hc in p.owncards)  // 暗金教水晶侍女；云雾王子；麦迪文男仆；隐秘咒术师
            {
                if (hc.card.name == CardDB.cardName.kabalcrystalrunner || hc.card.name == CardDB.cardName.cloudprince
                    || hc.card.name == CardDB.cardName.medivhsvalet || hc.card.name == CardDB.cardName.occultconjurer)
                {
                    needSecret = true;
                    break;
                }
            }
            switch (card.name)
            {
                //暗金教侍从（121 奥秘0费）
                case CardDB.cardName.kaballackey:
                    if (!hasSecretHand && p.ownMaxMana <= 8) return 50;//没有奥秘不要下
                    if (zeroSecret) return 500;//有0费奥秘不要下
                    return -7;//有奥秘

                case CardDB.cardName.kirintormage://肯瑞托法师
                    if (!hasSecretHand && p.ownMaxMana <= 8) return 20;//没有奥秘不要下
                    if (zeroSecret) return 500;
                    return -8;//有奥秘

                case CardDB.cardName.aluneth: //艾露尼斯
                    if (p.owncards.Count >= 5) return 500;
                    else return -30;

                //麦迪文的男仆
                case CardDB.cardName.medivhsvalet:
                    if (!hasSecretHead) return 10;
                    if (p.enemyHero.Hp <= 20)
                    {
                        if (target.isHero && !target.own) return -5;
                    }
                    return 0;
                //隐秘咒术师
                case CardDB.cardName.occultconjurer:
                    if (!hasSecretHead) return 50;
                    if (p.ownMinions.Count <= 5) return -12;  //确保有位置下2个44
                    return 0;
                //云雾王子
                case CardDB.cardName.cloudprince:
                    if (!hasSecretHead) return 60;
                    if (target.isHero && !target.own && p.enemyHero.Hp <= 15) return -20; //打敌方头，且敌方血量少
                    if (target.isHero && !target.own) return -6;
                    return 0;
                //暗月先知赛格
                case CardDB.cardName.saygeseerofdarkmoon:
                    // Todo:待更新，基于可以抽到的牌数：Triton.Game.HsCard.GetTag(GAME_TAG.TAG_SCRIPT_DATA_NUM_1)
                    if (p.owncards.Count >= 7) return 60;
                    return -(6 - p.owncards.Count) * (6 - p.owncards.Count) * 4; // 二次函数，牌越少越要出
                //低调的游客
                case CardDB.cardName.inconspicuousrider:
                    if (p.ownSecretsIDList.Count >= 5) return 20;  //确保头上或者牌库中还有不同类型奥秘可以挂
                    if (needSecret) return -8;
                    if (!hasSecretHead) return -8;  //头上没有优先级更高
                    return -5;
                // 部落特工
                case CardDB.cardName.hordeoperative: //根据敌人头上奥秘的数量，数量越多，越适合出
                    if (p.enemySecretCount == 0) return 5;
                    if (p.enemySecretCount == 1) return -5;
                    if (p.enemySecretCount == 2) return -15;
                    if (p.enemySecretCount >= 3) return -20;
                    break;
                // 军情七处渗透者
                case CardDB.cardName.si7infiltrator: //根据敌人头上有无奥秘
                    if (p.enemySecretCount >= 1) return -20;
                    if (p.enemyHero.cardClass == TAG_CLASS.MAGE || p.enemyHero.cardClass == TAG_CLASS.HUNTER
                      || p.enemyHero.cardClass == TAG_CLASS.PALADIN)   // 法师，猎人，圣骑士容易头上有奥秘
                    {
                        if (p.enemySecretCount == 0)
                            return 5;  //晚点出，等对方头上有奥秘
                    }
                    return 0;
                case CardDB.cardName.arcaneflakmage://对空奥术法师
                    int secret_count = 0;//当前mana可以出的secret
                    int available_mana = p.mana - card.cost;  //要扣掉奥术法师的cost
                    foreach (Handmanager.Handcard hc in p.owncards)
                    {
                        if (hc.card.Secret && available_mana >= hc.manacost)  //奥秘费用会变，不能用card.cost
                        {
                            available_mana -= hc.manacost;
                            secret_count++;
                        }
                    }
                    if (secret_count == 0)  //裸下
                    {
                        if (p.enemyMinions.Count >= 1 || p.enemyMaxMana >= 4)  //且对面有人或者费足够，送死
                            return 20;
                        else  //对面空场且费少，可能存活
                            return 5;
                    }
                    else // 可以触发
                    {
                        pen = -p.enemyMinions.Count * 2 * secret_count;
                        foreach (Minion mi in p.enemyMinions)
                        {
                            if (mi.Hp <= 2 * secret_count)
                                pen -= 4; // 每致死一位敌方随从，额外4分
                        }
                        return pen;
                    }
                //疯狂的科学家
                case CardDB.cardName.madscientist:
                    // 本身作为超模随从值得更高的优先级
                    if (!hasSecretHand) return -10;
                    return -5;
                //秘法学家
                case CardDB.cardName.arcanologist:
                    if (!hasSecretHand) return -5;
                    return 0;
                //远古谜团
                case CardDB.cardName.ancientmysteries:
                    if (!hasSecretHand) return -4;
                    if (zeroSecret) return 10;
                    return 0;
                case CardDB.cardName.kabalcrystalrunner://水晶侍女
                    //if (card.cost == 6) return 10;
                    //if (card.cost == 4) return -2;
                    //if (card.cost == 2) return -12;
                    //if (card.cost == 0) return -50;  // Todo: 这个写法不对，需要用hc.manacost，需要更改整个传参，否则稳定return 10
                    return 0;
                //非公平游戏
                case CardDB.cardName.riggedfairegame:
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -8;
                    if (p.ownWeapon.name == CardDB.cardName.aluneth)
                    {
                        if (hasSecretHead) return 50; // 不缺牌，不缺奥秘
                        if (needSecret) pen -= 3;
                    }
                    else
                    {//没有装备刀的情况 
                        if (p.owncards.Count >= 7) return 15;
                        if (p.owncards.Count <= 4 || p.enemyMaxMana <= 2) pen -= 10; //缺牌或者早期回合
                        if (p.enemyMinions.Count == 0) pen -= 8;  //对方场上没有随从，更容易触发
                        return pen;
                    }
                    return pen;
                //火焰结界
                case CardDB.cardName.flameward:
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -6;
                    if (needSecret) pen -= 5;
                    if (p.enemyMinions.Count > 0)
                    {
                        int kill_num = 0;
                        foreach (Minion mi in p.enemyMinions)
                        {
                            //对方随从生命值小于 3
                            if (mi.Hp <= 3) kill_num++;
                        }
                        pen -= kill_num * 5 + p.enemyMinions.Count;  //每能炸一个随从，加1，炸死一个，加5
                    }
                    return pen;
                case CardDB.cardName.iceblock://寒冰屏障
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -8;
                    if (p.ownHero.Hp <= 12) //有被斩杀风险
                        pen -= 7;
                    if (needSecret)
                        pen -= 4;   //优先级低于其他奥秘
                    return pen;

                case CardDB.cardName.explosiverunes://爆炸符文
                    pen = -5;
                    if (p.nextSecretThisTurnCost0)
                        pen -= 8;
                    if (needSecret)
                        pen -= 9;
                    if (p.enemyMinions.Count == 0 || p.enemyHero.Hp < 15)
                        pen -= 10;
                    return pen;
                case CardDB.cardName.counterspell://法术反制
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -6;
                    if (p.enemyHeroName == HeroEnum.priest && p.enemyMaxMana >= 4) pen -= 10;
                    if (p.enemyHeroName == HeroEnum.warlock && p.enemyMaxMana >= 4) pen -= 10;
                    if (p.enemyHeroName == HeroEnum.mage && p.enemyMaxMana >= 3) pen -= 5;
                    if (p.enemyMaxMana >= 7) pen -= 6;
                    if (p.ownMinions.Count >= 3) pen -= 10;
                    if (needSecret) pen -= 5;
                    return pen;

                case CardDB.cardName.duplicate://复制
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -7;
                    if (p.owncards.Count <= 3)
                        pen -= 4;
                    foreach (Minion m in p.ownMinions)  // 暗金教水晶侍女；云雾王子；隐秘咒术师
                    {
                        if (m.name == CardDB.cardName.kabalcrystalrunner || m.name == CardDB.cardName.cloudprince
                            || m.name == CardDB.cardName.occultconjurer)
                        {
                            pen -= 7;
                            break;
                        }
                    }
                    if (needSecret)
                    {
                        if (p.owncards.Count >= 7) pen -= 2;
                        else pen -= 5;
                    }
                    else
                    {
                        if (p.owncards.Count >= 7) return 20;
                    }
                    return pen;
                case CardDB.cardName.oasisally://绿洲联盟 
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -8;
                    if (needSecret)
                    {
                        if (p.ownMinions.Count >= 1)  //看是否有触发的机会
                            pen -= 7;
                        else
                            pen -= 6;
                    }
                    else
                    {
                        if (p.ownMinions.Count >= 1)
                            pen -= 5;
                        else
                            pen -= 3;
                    }
                    return pen;
                case CardDB.cardName.netherwindportal://虚空之风传送门
                    pen = 0;
                    if (p.nextSecretThisTurnCost0)
                        pen = -8;
                    if (p.enemyHeroName == HeroEnum.priest && p.ownMaxMana <= 3) pen -= 10;
                    if (p.enemyHeroName == HeroEnum.warlock && p.ownMaxMana <= 3) pen -= 10;
                    if (p.enemyHeroName == HeroEnum.mage && p.ownMaxMana <= 3) pen -= 10;
                    if (needSecret)
                        pen -= 5;
                    return pen;
                case CardDB.cardName.fireball://火球术
                    if (target.isHero && !target.own) //打敌方头
                    {
                        if (p.enemyHero.Hp <= 12)
                            return -15;
                        if (p.enemyHero.Hp > 20)  //不要太早打头，出其他牌
                            return 10;
                        return -2;  //一般用于斩杀，不用太早打敌方头
                    }
                    if (target.name == CardDB.cardName.flamewaker) //打火妖没问题
                        return -20;
                    if (!target.isHero) // 说明是随从
                    {
                        if (p.enemyHero.Hp <= 15) // 血量低，不应该打随从
                            return 15;
                        pen = target.Hp - 6;  // Todo: 要考虑法术加成
                        if (pen > 0)
                            return 0;  //打中的随从血量高，还ok
                        else
                            return -pen * 3; //血量低于6，说明伤害有浪费，要惩罚
                    }
                    return 2;

                case CardDB.cardName.forgottentorch://老旧的火把
                    if (target.isHero && !target.own)
                        if (p.enemyHero.Hp <= 10)  //敌方快挂了
                            return -8;
                        else
                            return -3;    //这个值要比一些奥秘值低
                    return 1;

                case CardDB.cardName.roaringtorch://炽热的火把
                    if (target.isHero && !target.own) return -6;
                    return 2;
            }  // switch 法师结束
            return 0;
        }

    }

}
